<script type="text/javascript">
    var a = null == null;
    document.write(a);
</script>

当函数执行时会产生一个叫做执行期上下文的内部对象。一个执行期上下文定义了函数执行时的环境，函数每次执行时对应的执行期上下文都是独一无二的，所以多次调用一个函数会导致创建多个执行期上下文，当函数执行完毕，它所产生的执行期上下文被销毁。
[[scope]]指的就是作用域，其中存储了运行执行期上下文的集合，这个集合程链式链接，我们把这个链式连接叫做作用域链
[[scope]]:每个js函数都是一个对象，对象中有些属性我们可以访问，但有些不可以，这些属性仅供js引擎存取，[[scope]]就是其中之一

查找变量：在哪个函数里面查找变量，就从那个函数的作用域链从顶端往低端查找

<script type="text/javascript">
	function a(){}
	//a被定义时
	//a.[[scope]] --> 0 : GO
	a();
	//a执行时
	//a.[[scope]] --> 0 : AO
	//				  1 : GO
</script>

<script type="text/javascript">
	function a(){
		function b (){
			var b =234;
		}
		//a执行时产生b定义,b保留a的劳动成果,b拿到a的作用域

		var a = 123;
		b();
		//b在执行时生成自己的AO，放在自己作用域的最顶端
	}

	var glob = 100;
	a();
</script>

<script type="text/javascript">
	function a(){
		function b(){
			var bb = 234;
			aa = 0;
		}
		var aa = 123;
		b();//一个函数执行完之后会销毁它的执行期上下文，回归到被定义的状态，等待下一次被执行，如果再次被执行，会产生一个新的AO在原来的基础上；
		console.log(aa);//在b里改变aa，执行完b后，在a里访问aa,如果aa的值变了，为123,说明b拿到的aAo和a自己的AO不是同一个；如果不变，为0，说明是同一个；假设不是同一个，b拿到的AO是谁生成的呢，没人给它生成新的AO，b拿的是a的AO的引用，b访问的AO就是a产生的AO；再换者说，全局GO总得是同一个人，大家都能改一下自身的，若是不同GO那就没有操作意义了
	}
	a();
</script>

<script type="text/javascript">
	function a(){
		function b(){
			var bb = 234;
			aa = 0;
		}
		var aa = 123;
		b();//b执行完，代表a执行完
	}
	a();//a执行完，会销毁自己[[scope]]上第0位的AO，由于a执行产生b定义，a的AO上存着变量b函数，a把0剪掉之后，说明b函数被抛弃没有了，不用等待下次被执行了；a回到被定义的状态，刚才的b没了
	a();//a再执行，再产生一个新的AO放到自己作用域的最顶端，上次产生的Ao已经仍没了，由于产生新AO会产生b定义，一个全新的b函数呈现出来，b拿到a的劳动成果，等待下一次被执行，被执行时会产生一个新bAO,放到自己作用域最顶端，形成一个作用域链，等待被查找变量
</script>

<script type="text/javascript">
	//想访问一个变量，找它的作用域链就完事了；在任何一个函数里找一个变量，只能在这个函数执行时产生的执行期上下文AO,产生的作用域链，真正它执行时产生的作用域链才是它真正的作用域;只有里面能看到外面的，外面不能访问里面
	function a(){
		function b(){
			console.log(cc);//不能访问c里面的东西，cc只能在c执行时才能被访问
			function c(){
				var cc = 123;//
			}
			c();
		}
		b();
	}
	a()//a执行才能导致b定义，a不执行，系统访问不了a里面东西
	//	a defined		a.[[scope]]		0 -->	GO

	//	a doing			a.[[scope]]		0 -->	aAO
	//									1 -->	GO	

	//	b defined		b.[[scope]]		0 -->	aAO
	//									1 -->	GO

	//	b doing			b.[[scope]]		0 -->	bAO
	//									1 -->	aAO
	//									2 -->	GO

	//	c defined		c.[[scope]]		0 -->	bAO
	//									1 -->	aAO
	//									2 -->	GO

	//	c doing			c.[[scope]]		0 -->	cAO
	//									1 --> 	bAO
	//									2 -->	aAO
	//									3 -->	GO
</script>